package com.myapp.ruyixing.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

public class ImageUtils {

	private static final DisplayImageOptions sImageDisplayOptions = new DisplayImageOptions.Builder()
			.imageScaleType(ImageScaleType.EXACTLY).cacheInMemory().build();

	public static void displayImage(String uri, ImageView imageView) {
		displayImage(uri, imageView, sImageDisplayOptions);
	}

	public static void displayImage(String uri, ImageView imageView,
			DisplayImageOptions options) {
		displayImage(uri, imageView, options, null);
	}

	public static void displayImage(String uri, ImageView imageView,
			DisplayImageOptions options, ImageLoadingListener listener) {
		try {

			String imageUri = uri;
			if (uri != null && uri.length() > 0) {
				if (uri.startsWith("/"))
					imageUri = "file://" + uri;

			}

			if (listener == null) {
				ImageLoader.getInstance().displayImage(imageUri, imageView,
						options);
			} else {
				ImageLoader.getInstance().displayImage(imageUri, imageView,
						options, listener);
			}
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static File compressBitmapFile(File src, String dstPath,
			int maxSize, int quality) {
		if (src == null || !src.exists()) {
			return null;
		}

		try {
			Bitmap bitmap = decodeSampledBitmapFromFile(src.toString(),
					maxSize, maxSize);
			if (bitmap != null) {
				File dst = new File(dstPath);
				if (dst.exists()) {
					dst.delete();
				}
				FileOutputStream fileout = new FileOutputStream(dst);
				bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fileout);
				fileout.close();

				bitmap.recycle();

				return dst;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
		}

		return null;
	}
	


	/**
	 * Decode and sample down a bitmap from a file to the requested width and
	 * height.
	 * 
	 * @param filename
	 *            The full path of the file to decode
	 * @param reqWidth
	 *            The requested width of the resulting bitmap
	 * @param reqHeight
	 *            The requested height of the resulting bitmap
	 * @return A bitmap sampled down from the original with the same aspect
	 *         ratio and dimensions that are equal to or greater than the
	 *         requested width and height
	 */
	public static synchronized Bitmap decodeSampledBitmapFromFile(
			String filename, int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filename, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		options.inPreferredConfig = Bitmap.Config.RGB_565;
		options.inDither = true;

		try {
			return BitmapFactory.decodeFile(filename, options);
		} catch (OutOfMemoryError e) {
		}

		return null;
	}

	/**
	 * Calculate an inSampleSize for use in a
	 * {@link android.graphics.BitmapFactory.Options} object when decoding
	 * bitmaps using the decode* methods from {@link BitmapFactory}. This
	 * implementation calculates the closest inSampleSize that will result in
	 * the final decoded bitmap having a width and height equal to or larger
	 * than the requested width and height. This implementation does not ensure
	 * a power of 2 is returned for inSampleSize which can be faster when
	 * decoding but results in a larger bitmap which isn't as useful for caching
	 * purposes.
	 * 
	 * @param options
	 *            An options object with out* params already populated (run
	 *            through a decode* method with inJustDecodeBounds==true
	 * @param reqWidth
	 *            The requested width of the resulting bitmap
	 * @param reqHeight
	 *            The requested height of the resulting bitmap
	 * @return The value to be used for inSampleSize
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			if (width > height) {
				inSampleSize = Math.round((float) height / (float) reqHeight);
			} else {
				inSampleSize = Math.round((float) width / (float) reqWidth);
			}

			// This offers some additional logic in case the image has a strange
			// aspect ratio. For example, a panorama may have a much larger
			// width than height. In these cases the total pixels might still
			// end up being too large to fit comfortably in memory, so we should
			// be more aggressive with sample down the image (=larger
			// inSampleSize).

			final float totalPixels = width * height;

			// Anything more than 2x the requested pixels we'll sample down
			// further.
			final float totalReqPixelsCap = reqWidth * reqHeight * 2;

			while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
				inSampleSize++;
			}
		}
		return inSampleSize;
	}
}
